
/*
*   主要是用于 tree jd 的操作
*   一般tree json 格式 [{code,name,children},...]
*    children :[{},{}]
* */

// rc Recursive
export const findParent=function(tree,code) {
    let result;
    function find(rcTree,p){
        if(result)
            return;
        for(let o of rcTree){
            if(o.code == code){
                result = p;
                break;
            }
            if(o.children)
                find(o.children,o);
        }
    }
    find(tree,null);
    return result;
};

/* jd like {code , children:{code,...}}
*  无父节点 指针
*  只能递归找出
* */
export const findParentsCodeByRc=function(tree,code){
    let parentsCode = [];
    let p;
    while(true){
        p = findParent(tree,p?p.code:code);
        if(p)
            parentsCode.push(p.code);
        else
            break;
    }
    return parentsCode;
}
/*
*   这里返回 的 是所有的父级节点 , 针对 没有父级 链接的结构
* */
export const findAllParentByCode=function(tree,code){
    let parents = [];
    let p;
    while(true){
        p = findParent(tree,p?p.code:code);
        if(p)
            parents.push(p);
        else
            break;
    }
    return parents;
}

export const findAllParents=function(node){
    let parents = [] ;
    let p = node._parent
    while(p){
        parents.push(p);
        p = p._parent;
    }
    return parents.reverse();
}

export const findNodeByCode=function(tree,code){
    let result;
    function find(rcTree) {
        if(result)
            return;
        for(let o of rcTree){
            if(o.code == code){
                result = o ;
                break;
            }else {
                if(o.children) {
                    find(o.children);
                }
            }
        }
    }
    find(tree);
    return result;
}

export const findNameByCode=function(tree,code){
    let result;
    function findName(rcTree) {
        if(result)
            return;
        for(let o of rcTree){
            if(o.code == code){
                result = o.name ;
                break;
            }else {
                if(o.children) {
                    findName(o.children);
                }
            }
        }
    }
    findName(tree);
    return result;
}


//
// flat json 转换 成 tree json  最多 支持 到 6 层 ,最少 2 层
//  一次循环 搞定 ，办法笨了点，但是 避免 多层循环或者是递归。
// attr[0]  代表  treeNodeId
// attr[1]  代表  treeNodeName
// 增加别名
/*
 metaAttr{d1Attr:["provCode regionCode","provName regionName"],
	      d2Attr:["cityCode regionCode","cityName regionName"],
	      d3Attr:["distCode regionCode","distName regionName"]}

	"provCode regionCode" provCode flat json 的  属性
	                      regionCode  转换后 treejson 的属性 可以不填 。

 */
export const starToTree = function(flatJson, metaAttr) {

    function addJsonAttr(vObj, attr, dnJson) {
        for(let xAttr of attr) {
            dnJson[xAttr.alias] = vObj[xAttr.key];
        }
    };

    function attrToAttrJson(oldAttr) {
        let newAttr = new Array;
        let tmpStr;
        for(let xOldAttr of oldAttr) {
            let xObj = {};
            tmpStr = xOldAttr.trim().split(/\s+/);
            xObj.key = tmpStr[0];
            xObj.alias = !tmpStr[1] ? tmpStr[0] : tmpStr[1];
            newAttr.push(xObj);
        }
        return newAttr;
    };

    let treeJson = [];
    let vObj;

    // 第一层
    let d1Attr = attrToAttrJson(metaAttr.d1Attr);
    let d1KeyValue = "";
    let d1Key = d1Attr[0].key;
    let d1Name = d1Attr[1].key;
    let arrayD1Child;

    //第二层
    let d2Attr = attrToAttrJson(metaAttr.d2Attr);
    let d2KeyValue = "";
    let d2Key = d2Attr[0].key;
    let d2Name = d2Attr[1].key;
    let arrayD2Child;

    //第三层

    let d3Attr  ;
    let d3KeyValue = "";
    let d3Key ;
    let d3Name ;
    let arrayD3Child;

    if(!!metaAttr.d3Attr) {
        d3Attr = attrToAttrJson(metaAttr.d3Attr);
        d3Key = d3Attr[0].key;
        d3Name = d3Attr[1].key;
    }

    let d4Attr  ;
    let d4KeyValue = "";
    let d4Key  ;
    let d4Name  ;
    let arrayD4Child;

    //第四层
    if(!!metaAttr.d4Attr) {
        d4Attr = attrToAttrJson(metaAttr.d4Attr);
        d4Key = d4Attr[0].key;
        d4Name = d4Attr[1].key;

    }

    let d5Attr ;
    let d5KeyValue = "";
    let d5Key  ;
    let d5Name  ;
    let arrayD5Child;

    //第五层
    if(!!metaAttr.d5Attr) {
        d5Attr = attrToAttrJson(metaAttr.d5Attr);
        d5Key = d5Attr[0].key;
        d5Name = d5Attr[1].key;
    }

    let d6Attr;
    let d6Key ;
    let d6Name ;

    //第六层
    if(!!metaAttr.d6Attr) {
        d6Attr = attrToAttrJson(metaAttr.d6Attr);
        d6Key = d6Attr[0].key;
        d6Name = d6Attr[1].key;
    }

    for(let i = 0, len = flatJson.length; i < len; i++) {
        vObj = flatJson[i];

        if(d1KeyValue != vObj[d1Key]) {
            let d1Json = new Object();
            treeJson.push(d1Json);
            d1Json["code"] = vObj[d1Key];
            d1Json["name"] = vObj[d1Name];
            d1Json["treeLevel"] = 1;

            addJsonAttr(vObj, d1Attr, d1Json);

            // 如果存在子节点
            /*  存在子节点 2种情况 都要考虑
             *  1： 本行子节点记录 为空 ，子节点 从下行开始 。
                2： 本行子节点记录不为空 ，子节点 从本行开始。
                                这里 只增加 空的子节点，子节点内容 在下一个if 语句.
             */
            d1KeyValue = vObj[d1Key];

            let d1HasChild;
            if(!!vObj[d2Key]) d1HasChild = true;
            else if(i < len - 1 && vObj[d1Key] == flatJson[i + 1][d1Key]) d1HasChild = true;
            else d1HasChild = false;

            if(d1HasChild == true) {
                arrayD1Child = new Array();
                d1Json["children"] = arrayD1Child;
                // d1Json["hasChildren"]  =  true ;
            }

            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d2Key]) continue;

        }

        // 第二层 数据
        if(d2KeyValue != vObj[d2Key]) {
            let d2Json = new Object();
            arrayD1Child.push(d2Json);

            d2Json["code"] = vObj[d2Key];
            d2Json["name"] = vObj[d2Name];
            d2Json["treeLevel"] = 2;
            addJsonAttr(vObj, d2Attr, d2Json);

            d2KeyValue = vObj[d2Key];

            if (typeof d3Key  == "undefined") continue;

            let d2HasChild;
            if((!!d3Key)&&(!!vObj[d3Key])) d2HasChild = true;
            else if(i < len - 1 && vObj[d2Key] == flatJson[i + 1][d2Key]) d2HasChild = true;
            else d2HasChild = false;

            if(d2HasChild == true) {
                arrayD2Child = new Array();
                d2Json["children"] = arrayD2Child;
                // d2Json["hasChildren"]  =  true ;
            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d3Key]) continue;
        }

        // 第三层 数据
        if(!!d3Key && d3KeyValue != vObj[d3Key]) {
            let d3Json = new Object();
            arrayD2Child.push(d3Json);

            d3Json["code"] = vObj[d3Key];
            d3Json["name"] = vObj[d3Name];
            d3Json["treeLevel"] = 3;
            addJsonAttr(vObj, d3Attr, d3Json);

            d3KeyValue = vObj[d3Key];

            if (typeof d4Key  == "undefined") continue;

            let d3HasChild;
            if(!!vObj[d4Key]) d3HasChild = true;
            else if(i < len - 1 && vObj[d3Key] == flatJson[i + 1][d3Key]) d3HasChild = true;
            else d3HasChild = false;

            if(d3HasChild == true) {
                arrayD3Child = new Array();
                d3Json["children"] = arrayD3Child;
                // d3Json["hasChildren"]  =  true ;
            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d4Key]) continue;
        }

        // 第四层 数据
        if(!!d4Key && d4KeyValue != vObj[d4Key]) {
            let d4Json = new Object();
            arrayD3Child.push(d4Json);

            d4Json["code"] = vObj[d4Key];
            d4Json["name"] = vObj[d4Name];
            d4Json["treeLevel"] = 4;
            addJsonAttr(vObj, d4Attr, d4Json);

            d4KeyValue = vObj[d4Key];

            if (typeof d5Key  == "undefined") continue;
            let d4HasChild;
            if(!!vObj[d5Key]) d4HasChild = true;
            else if(i < len - 1 && vObj[d4Key] == flatJson[i + 1][d4Key]) d4HasChild = true;
            else d4HasChild = false;

            if(d4HasChild == true) {
                arrayD4Child = new Array();
                d4Json["children"] = arrayD4Child;
                // d4Json["hasChildren"]  =  true ;
            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d5Key]) continue;
        }

        // 第五层 数据
        if(!!d5Key && d5KeyValue != vObj[d5Key]) {
            let d5Json = new Object();
            arrayD4Child.push(d5Json);

            d5Json["code"] = vObj[d5Key];
            d5Json["name"] = vObj[d5Name];
            d5Json["treeLevel"] = 5;
            addJsonAttr(vObj, d5Attr, d5Json);

            d5KeyValue = vObj[d5Key];

            if (typeof d6Key  == "undefined") continue;

            let d5HasChild;
            if(!!vObj[d6Key]) d5HasChild = true;
            else if(i < len - 1 && vObj[d5Key] == flatJson[i + 1][d5Key]) d5HasChild = true;
            else d5HasChild = false;

            if(d5HasChild == true) {
                arrayD5Child = new Array();
                d5Json["children"] = arrayD5Child;
                // d5Json["hasChildren"]  =  true ;
            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d6Key]) continue;
        }

        // 第六层 数据
        if(!!d6Key && d6KeyValue != vObj[d6Key]) {
            let d6Json = new Object();
            arrayD5Child.push(d6Json);

            d6Json["code"] = vObj[d6Key];
            d6Json["name"] = vObj[d6Name];
            d6Json["treeLevel"] = 6;
            addJsonAttr(vObj, d6Attr, d6Json);

            d6KeyValue = vObj[d6Key];
        }

    }
    return treeJson;
};


export const starToCodeJson = function(flatJson, metaAttr) {

    function addJsonAttr(vObj, attr, dnJson) {
        for(let z in attr) {
            if (z>1)
                dnJson[attr[z].alias] = vObj[attr[z].key];
        }
    };

    function attrToAttrJson(oldAttr) {
        let newAttr = new Array;
        let tmpStr;
        for(let xOldAttr of oldAttr) {
            let xObj = {};
            tmpStr = xOldAttr.trim().split(/\s+/);
            xObj.key = tmpStr[0];
            xObj.alias = !tmpStr[1] ? tmpStr[0] : tmpStr[1];
            newAttr.push(xObj);
        }
        return newAttr;
    };

    let treeJson = [];
    let vObj;

    // 第一层
    let d1Attr = attrToAttrJson(metaAttr.d1Attr);
    let d1KeyValue = "";
    let d1Key = d1Attr[0].key;
    let d1Name = d1Attr[1].key;
    let arrayD1Child;

    //第二层
    let d2Attr = attrToAttrJson(metaAttr.d2Attr);
    let d2KeyValue = "";
    let d2Key = d2Attr[0].key;
    let d2Name = d2Attr[1].key;
    let arrayD2Child;

    //第三层

    let d3Attr  ;
    let d3KeyValue = "";
    let d3Key ;
    let d3Name ;
    let arrayD3Child;

    if(!!metaAttr.d3Attr) {
        d3Attr = attrToAttrJson(metaAttr.d3Attr);
        d3Key = d3Attr[0].key;
        d3Name = d3Attr[1].key;
    }

    let d4Attr  ;
    let d4KeyValue = "";
    let d4Key  ;
    let d4Name  ;
    let arrayD4Child;

    //第四层
    if(!!metaAttr.d4Attr) {
        d4Attr = attrToAttrJson(metaAttr.d4Attr);
        d4Key = d4Attr[0].key;
        d4Name = d4Attr[1].key;

    }

    let d5Attr ;
    let d5KeyValue = "";
    let d5Key  ;
    let d5Name  ;
    let arrayD5Child;

    //第五层
    if(!!metaAttr.d5Attr) {
        d5Attr = attrToAttrJson(metaAttr.d5Attr);
        d5Key = d5Attr[0].key;
        d5Name = d5Attr[1].key;
    }

    let d6Attr;
    let d6Key ;
    let d6Name ;

    //第六层
    if(!!metaAttr.d6Attr) {
        d6Attr = attrToAttrJson(metaAttr.d6Attr);
        d6Key = d6Attr[0].key;
        d6Name = d6Attr[1].key;
    }

    for(let i = 0, len = flatJson.length; i < len; i++) {
        vObj = flatJson[i];

        if(d1KeyValue != vObj[d1Key]) {
            let d1Json = new Object();
            treeJson.push(d1Json);
            d1Json["code"] = vObj[d1Key];
            d1Json["name"] = vObj[d1Name];

            addJsonAttr(vObj, d1Attr, d1Json);

            // 如果存在子节点
            /*  存在子节点 2种情况 都要考虑
             *  1： 本行子节点记录 为空 ，子节点 从下行开始 。
                2： 本行子节点记录不为空 ，子节点 从本行开始。
                                这里 只增加 空的子节点，子节点内容 在下一个if 语句.
             */
            d1KeyValue = vObj[d1Key];

            let d1HasChild;
            if(!!vObj[d2Key]) d1HasChild = true;
            else if(i < len - 1 && vObj[d1Key] == flatJson[i + 1][d1Key]) d1HasChild = true;
            else d1HasChild = false;

            if(d1HasChild == true) {
                arrayD1Child = new Array();
                d1Json["children"] = arrayD1Child;

            }

            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d2Key]) continue;

        }

        // 第二层 数据
        if(d2KeyValue != vObj[d2Key]) {
            let d2Json = new Object();
            arrayD1Child.push(d2Json);

            d2Json["code"] = vObj[d2Key];
            d2Json["name"] = vObj[d2Name];

            addJsonAttr(vObj, d2Attr, d2Json);

            d2KeyValue = vObj[d2Key];

            if (typeof d3Key  == "undefined") continue;

            let d2HasChild;
            if((!!d3Key)&&(!!vObj[d3Key])) d2HasChild = true;
            else if(i < len - 1 && vObj[d2Key] == flatJson[i + 1][d2Key]) d2HasChild = true;
            else d2HasChild = false;

            if(d2HasChild == true) {
                arrayD2Child = new Array();
                d2Json["children"] = arrayD2Child;

            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d3Key]) continue;
        }

        // 第三层 数据
        if(!!d3Key && d3KeyValue != vObj[d3Key]) {
            let d3Json = new Object();
            arrayD2Child.push(d3Json);

            d3Json["code"] = vObj[d3Key];
            d3Json["name"] = vObj[d3Name];

            addJsonAttr(vObj, d3Attr, d3Json);

            d3KeyValue = vObj[d3Key];

            if (typeof d4Key  == "undefined") continue;

            let d3HasChild;
            if(!!vObj[d4Key]) d3HasChild = true;
            else if(i < len - 1 && vObj[d3Key] == flatJson[i + 1][d3Key]) d3HasChild = true;
            else d3HasChild = false;

            if(d3HasChild == true) {
                arrayD3Child = new Array();
                d3Json["children"] = arrayD3Child;
                // d3Json["hasChildren"]  =  true ;
            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d4Key]) continue;
        }

        // 第四层 数据
        if(!!d4Key && d4KeyValue != vObj[d4Key]) {
            let d4Json = new Object();
            arrayD3Child.push(d4Json);

            d4Json["code"] = vObj[d4Key];
            d4Json["name"] = vObj[d4Name];

            addJsonAttr(vObj, d4Attr, d4Json);

            d4KeyValue = vObj[d4Key];

            if (typeof d5Key  == "undefined") continue;
            let d4HasChild;
            if(!!vObj[d5Key]) d4HasChild = true;
            else if(i < len - 1 && vObj[d4Key] == flatJson[i + 1][d4Key]) d4HasChild = true;
            else d4HasChild = false;

            if(d4HasChild == true) {
                arrayD4Child = new Array();
                d4Json["children"] = arrayD4Child;
                // d4Json["hasChildren"]  =  true ;
            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d5Key]) continue;
        }

        // 第五层 数据
        if(!!d5Key && d5KeyValue != vObj[d5Key]) {
            let d5Json = new Object();
            arrayD4Child.push(d5Json);

            d5Json["code"] = vObj[d5Key];
            d5Json["name"] = vObj[d5Name];

            addJsonAttr(vObj, d5Attr, d5Json);

            d5KeyValue = vObj[d5Key];

            if (typeof d6Key  == "undefined") continue;

            let d5HasChild;
            if(!!vObj[d6Key]) d5HasChild = true;
            else if(i < len - 1 && vObj[d5Key] == flatJson[i + 1][d5Key]) d5HasChild = true;
            else d5HasChild = false;

            if(d5HasChild == true) {
                arrayD5Child = new Array();
                d5Json["children"] = arrayD5Child;
                // d5Json["hasChildren"]  =  true ;
            }
            // 本行子节点为空  ，本次循环结束  开始下一次
            if(!vObj[d6Key]) continue;
        }

        // 第六层 数据
        if(!!d6Key && d6KeyValue != vObj[d6Key]) {
            let d6Json = new Object();
            arrayD5Child.push(d6Json);

            d6Json["code"] = vObj[d6Key];
            d6Json["name"] = vObj[d6Name];

            addJsonAttr(vObj, d6Attr, d6Json);

            d6KeyValue = vObj[d6Key];
        }

    }
    return treeJson;
};


/*
*  层级 flat  to  tree
*  层级 [{ code,name,pCode},...]
* */
//为控件 转换 xtree  默认 只显示根节点
export const hierarchyToTree  = function(hierarchy){
    if(!hierarchy || hierarchy.length<1)
        return [];
    function findNodeInHierarchy(code){
        let result ;
        for(let node of hierarchy){
            if (code == node.code){
                result = node;
                break;
            }
        }
        return result;
    };
    
    let roots = [];
    hierarchy.forEach(node =>{
        //存在 父子关系 的
        if(node.pCode){
            //1：父节点 增加 子节点
            let p=findNodeInHierarchy(node.pCode);
            if(p){
                if(p.children)
                    p.children.push(node);
                else{
                    p.children = [];
                    p.children.push(node);
                }
            }else
                node.pCode='';
        }
    });

    hierarchy.forEach(node =>{
        if(!node.pCode){
            roots.push(node);
        }

    });
    return roots;

};

export const setTreeLevel=function(tree,level){
    let maxLevel = 1;
    function setLevel(rcTree,rcLevel){
        if(rcLevel>maxLevel)
            maxLevel=rcLevel;
        for(let t of rcTree){
            t._level = rcLevel;
            if(t.children && t.children.length>0)
                setLevel(t.children,rcLevel+1);
        }
    }
    setLevel(tree,level?level:1);
    return maxLevel;
}

export const setTreeLeafCount=function(tree){
    function setLeafCount(rcTree,parent){
        var leafCount = 0;
        for(let t of rcTree){
            if(t.children)
                leafCount += setLeafCount(t.children,t);
            else
                leafCount += 1;
        }
       if(parent)
           parent._leafCount = leafCount;
        return leafCount;
    }
    setLeafCount(tree,null);
};

export const setTreeSpan=function(tree,maxLevel){
    let depth = maxLevel?maxLevel:getTreeMaxLevel(tree);
    function setSpan(rcTree) {
        for(let t of rcTree){
            t._colspan = t._leafCount;
            if(t.children){
                t._rowspan = 1;
                setSpan(t.children);
            }else
                t._rowspan = depth - t._level+1;
        }
    }
    setSpan(tree);
};

/*Y轴span*/
export const setTreeTransposeSpan=function(tree,maxLevel){
    let depth = maxLevel?maxLevel:getTreeMaxLevel(tree);
    function setSpan(rcTree) {
        for(let t of rcTree){
            //t._colspan = t._leafCount;
            t._rowspan = t._leafCount;
            if(t.children){
                //t._rowspan = 1;
                t._colspan = 1;
                setSpan(t.children);
            }else
                //t._rowspan = depth - t._level+1;
                t._colspan = depth - t._level+1;
        }
    }
    setSpan(tree);
};

export const getTreeMaxLevel = function(tree){
    let maxLevel = 1;
    function getLevel(rcTree){
        for(let t of rcTree){
            if(t._level>maxLevel)
                maxLevel= t._level;
            if(t.children)
                getLevel(t.children);
        }
    }
    getLevel(tree);
    return maxLevel;
}

export const setTreeAttr=function(tree,level,parent){
    function setAttr(rcTree,rcLevel,p){
        for(let n of rcTree){
            n._show = rcLevel==1?true:false;
            n._expand =false;
            if(p) n._parent = p;
            n._level = rcLevel;
            if(n.children && n.children.length>0)
                setAttr(n.children,rcLevel+1,n);
        }
    }
    setAttr(tree,level?level:1,parent);
}

//某个父级下面插入节点
export const insertNode=function(tree,pCode,node){

    /*已存在*/
    if(findNodeByCode(tree,node.code))
        return 2;
    try{
        let p =  findNodeByCode(tree,pCode);
        if(p){
            if(!p.children)
                p.children = [];
            p.children.push(node);
            setTreeAttr([node],p._level+1,p);
        }else{
            setTreeAttr([node]);
            tree.push(node);
        }
        //插入后 节点要显示
        while(p){
            expandByNode(p,true);
            p=p._parent;
        }
        // 成功
        return 1
    }catch {
        console.log('节点插入失败 ');
        return 0
    }

    return result;
}

//删除节点
export const deleteNodeByCode = function(tree,code){
    let node = findNodeByCode(tree,code);
    let p = node._parent;
    if(p)
         p.children = p.children.filter(item => item.code!=code);
    else{
        let index = -1;
        for(let i =0;i<tree.length;i++){
            if(tree[i].code== code){
                index = i ;
                break;
            }
        }
        if (index>-1){
            tree.splice(index,1);
        }
    }
    return 1;
}

export const findJsonByCode=function(json,code){
	if(!json)
	   return null;
    for(let j of json){
        if(j.code == code)
            return j;
    }
}

//无 treeLevel 的
export const findLevelByCode=function(tree,code){
    let result;
    function getLevel(rcTree,rcLevel){
        if(result) return;
        for(let item of rcTree) {
            if(item.code == code ){
                result = rcLevel;
                break;
            }
            else {
                if(item.children)
                    getLevel(item.children,rcLevel+1);
            };
        };
    }
    getLevel(tree,1);
    return result;
};

/*
*  1：子节点处理
*      所有得子节点 状态同于 该节点
*  2: 父节点
* */
export const checkNodeByCode=function(tree,code){
    let pCheck ;
    function getCheckByChild(rcTree){
        if(pCheck==2)
            return;
        rcTree.forEach(n =>{
            if(pCheck == -1)
                pCheck = n._check?n._check:0;
            if(pCheck != (n._check?n._check:0)){
                pCheck =2;
                return;
            }
            if(n.children)
                getCheckByChild(n.children)
        })
    }

    function childCheck(rcTree,check){
        rcTree.forEach(n =>{
            n._check = check;
            if(n.children)
                childCheck(n.children,check);
        })
    }

    let node = findNodeByCode(tree,code);
    node._check = node._check==2?1:node._check==1?0:1;
    //子节点处理
    if(node.children)
        childCheck(node.children,node._check);
    //父节点处理
    let p =node._parent;
    while(p){
        pCheck =-1;
        getCheckByChild(p.children);
        p._check = pCheck;
        p = p._parent;
    }
}

/*
children 数组
* */

//所有 直接 的和间接的子节点
export const getAllChildren=function(node){
   let allChildren = [];
   function InnerGetChildren(rcTree){
       if(rcTree){
           for(let n of rcTree){
               allChildren.push(n);
               if(n.children)
                   InnerGetChildren(n.children);
           }
       }
    }
    InnerGetChildren(node.children);
    return allChildren;
}

/*
  获取全部的 checked 的 ，如果子节点全部选中，只取父节点即可。
*/
export const getAllChecked = function(tree){
    let allChecked =[];

    function addCheck(rcTree){
        for(let n of rcTree){
            switch(n._check){
                case 1:
                    allChecked.push(n);
                    break;
                case 2:
                    if(n.children)
                         addCheck(n.children);
                    break;
            }
        }
    }
    addCheck(tree);
    return allChecked;
};
//所有 直接 的和间接的parent节点
export const getAllParent=function(node){
    let allParent = [];
    let pNode = node;
    while(pNode._parent){
        allParent.push(pNode._parent);
        pNode = pNode._parent;
    }
    return allParent;
};


export const getNodeByLevel=function(tree,level){
    let nodes = [];
    function getNode(rcTree){
        if(rcTree){
            for(let n of rcTree){
                if(n._level == level)
                    nodes.push(n);
                if(n.children && n._level<level)
                    getNode(n.children);
            }
        }
    }
    getNode(tree);
    return nodes;
}

/*
* 默认 显示  _show  :
* 默认       _expand:
* */
export const expandNodeByCode=function(tree,code,status){
    let node = findNodeByCode(tree,code);
    expandByNode(node);
}


export const expandByLevel=function(tree,level){
    let iLevel = level-0;
    if(level == -1)
        iLevel = 999;
    function expand(rcTree){
        for(let node of rcTree){
            node._show = (node._level<=iLevel+1)?true:false;
            if(node.children){
                node._expand = (node._level<=iLevel)?true:false;
                expand(node.children)
            }
        }
    }
    expand(tree);
};

export const expandByNode=function(node,status){
    let children = getAllChildren(node);
    if(status==undefined)
         node._expand = !node._expand;
    else
         node._expand = status;
    //子节点的显示跟着 父节点的 _expand 和_show
    for(let c of children){
        c._show = c._parent._expand && c._parent._show;
    }
};



export const expandInit=function(tree,expand){
    let by = expand.split(' ')[0];
    let value =expand.split(' ')[1];
    switch(by){
        case 'node':
            let node = findNodeByCode(tree,value);
            let parentAndSelf = findAllParents(node);
            parentAndSelf.push(node);
            for(let n of parentAndSelf){
                expandByNode(n);
            }
            break;
        case 'level':
            expandByLevel(tree,value);
            break;
    }
};

export const treeFilter=function(tree,callback,value){
    let filterNode =[];
    //为方便同时增加 父节点的指向  主要是为了要保留结构
    function filter(rcTree,parent){
        for(let n of rcTree){
            n._parent = parent;
            if(callback(n,value)){
                n._filter =  true;
                filterNode.push(n);
            }else
                n._filter =  false;
            if(n.children)
                filter(n.children,n);
        }
    }
    //处理满足条件的 node
    filter(tree,null);
    // 满足条件的节点 父节点处理 也满足 ，主要是为了保留结构
   for(let n of filterNode){
       let p = n._parent;
       while(p){
           p._filter=true;
           p=p._parent;
       }
   }
}

export const getTreeLeaf=function(tree,callback){
    let leaf =[];
    function getLeaf(rcTree){
        for(let c of rcTree){
            if(c.children)
                getLeaf(c.children);
            else{
                if(callback && !callback(c))
                    continue;
                leaf.push(c);
            }
        }
    }
    getLeaf(tree);
    return leaf;
}


export const copyTree=function(tree,callback){
    let treeOfCopy=[] ;
    function copy(rcTree,childrenArray){
        for(let c of rcTree){
            //存在 回调函数 并且回调为false 不做处理  跳至下一个
            if(callback && !callback(c))
                continue;
            let node = {...c};
            childrenArray.push(node)
            if(c.children)
                copy(c.children,node.children=[])
        }
    }
    copy(tree,treeOfCopy);
    return treeOfCopy ;
}

export const getArrayOfTreeNode=function(tree){
    let arrayTree=[];
    function pushNode(rcTree){
        for(let n of rcTree){
            arrayTree.push(n);
            if(n.children)
                pushNode(n.children);
        }
    }
    pushNode(tree);
    return arrayTree;
}

/*
*  构造 Y轴 matrix
* */
export const getAixsYMatrix=function(tree,leafsY){
    //let depth = maxLevel?maxLevel:getTreeMaxLevel(tree);
    let YMatrix = [];
    let leafs =leafsY?leafsY:getTreeLeaf(tree);
    for(let i =0;i<leafs.length;i++){
        YMatrix.push([]);
    }
    // _level 就是 他的横坐标
    // 他的第一个 叶子数的 index 就是 他的纵坐标
    for(let j =0;j<leafs.length;j++){
        let node = leafs[j];
        while(node){
            YMatrix[j][node._level-1] = node;
            node._inMatrix = true;
            node = node._parent && !node._parent._inMatrix?node._parent:null;
        }
    }
    return YMatrix;
}

/*
*  构造 X轴 matrix
* */
export const getAixsXMatrix=function(tree,maxLevel){
    let depth = maxLevel?maxLevel:getTreeMaxLevel(tree);
    let XMatrix = [];
    for(let i =0;i<depth;i++){
        XMatrix.push(getNodeByLevel(tree,i+1));
    }
    return XMatrix;
}

/*
*  构造 X轴 matrix 新的 ，以坐标的方式
*
* */
export const getAixsXMatrixNew=function(tree,maxLevel){
    let depth = maxLevel?maxLevel:getTreeMaxLevel(tree);
    let XMatrix = [];
    for(let i =0;i<depth;i++){
        XMatrix.push([]);
    }
    for(let i =0;i<depth;i++){
        let nodes = getNodeByLevel(tree,i+1);
        let j=0;
        for(let n of nodes){
            while(true){
                if(XMatrix[i][j])
                    j=j+1;
                else
                    break;
            }
            n._colspan = n._colspan?n._colspan:1;
            n._rowspan = n._rowspan?n._rowspan:1;
            if(n._colspan>1 || n._rowspan>1)
                fillMatrixByItem(XMatrix,[i,i+n._rowspan-1],[j,j+n._colspan-1],n);
            else
                XMatrix[i][j] = n;
            j +=n._colspan;
        }
    }
    return XMatrix;
}


export const setTreeSumNode =function (tree,leafs){
    function getFirstLeafIndex(node){
        let leaf ;
        let parent;
        let index = -1;
        for(let i=0;i<leafs.length;i++){
            leaf = leafs[i]
            parent =leaf._parent;
            while(parent){
                if(node == parent){
                    index = i;
                    break;
                }
                parent=parent._parent;
            }
            if(index>-1)
                break;
        }
        return index;
    }
    for(let l of leafs){
        let p = l._parent;
        while(p && !(p._setSumNode)){
            if(p.children.length>1){
                let sumNode = {code:p.code+',_sum',name:'合计',_type:'sum',_parent:p,_level:p._level+1};
                sumNode._from = getFirstLeafIndex(p);
                sumNode._to = sumNode._from+p._leafCount-1;
                p.children.push(sumNode);
            }
            p._setSumNode = true;
            p = p._parent;
        }
    }
    //根节点 增加一个汇总
    if(tree.length>1)
        tree.push({code:'_sum',name:'合计',_type:'sum',_parent:"",_level:1,
            _from:0,_to:leafs.length-1});

}

export const getSubCubeData=function(matrix,Ys,Xs){
    let datas = [] ;
    for(let Y=Ys[0]-0;Y<=Ys[1]-0;Y++){
        for(let X=Xs[0]-0;X<=Xs[1]-0;X++){
            if(matrix[Y][X])
                datas.push(...matrix[Y][X])
        }
    }
    return datas;
};

export const getInitMatrix=function(Ylength,Xlength){
    let matrix =[];
    for(let i=0;i<Ylength;i++){
        matrix.push(new Array(Xlength));
    }
    return matrix;
}

export const fillMatrixByItem = function(matrix,Ys,Xs,item){
    for(let Y=Ys[0]-0;Y<=Ys[1]-0;Y++){
        for(let X=Xs[0]-0;X<=Xs[1]-0;X++){
            matrix[Y][X] = item;
        }
    }
}